#include <iostream>
#include <fstream>
#include <string>
#include <vector>

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <boost/foreach.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>


#include "c_config.h"


using namespace std;
using namespace boost;

namespace dhd
{
namespace client
{
   
   typedef vector<string> SV;

   
   void parse_server( SV & svec, int nline, ServerCFG & cfg )
   {
       if ( svec.size() < 2 )
           throw ConfigurationError("Invalid server definition", nline );
       
       SV hvec;
       split( hvec, svec[1], is_any_of(":") );
       
       if ( hvec.size() != 2 )
           throw ConfigurationError("Missing port number", nline);
       
       try
       {
           cfg.hostname = hvec[0];
           cfg.port     = boost::lexical_cast<int>(hvec[1]);
       } 
       catch ( boost::bad_lexical_cast )
       {
           throw ConfigurationError( "Invalid port number", nline );
       }
       
       for( int i = 2; i < svec.size(); i++ )
       {
           if ( svec[i] == "use_ssl" )
               cfg.use_ssl = true;
           if ( svec[i] == "use_srp" )
               cfg.use_srp = true;
       }
   }
   

   void parse_srp( SV & svec, int nline, 
                   std::string & srp_username,
                   std::string & srp_password_file,
                   std::string & srp_password )
   {
       if ( svec.size() != 2 )
           throw ConfigurationError("Invalid server definition", nline );
       
       SV hvec;
       split( hvec, svec[1], is_any_of(":") );
       
       if ( hvec.size() != 2 )
           throw ConfigurationError("Invalid SRP credentials. Format is username:password_file", nline);
       
       srp_username      = hvec[0];
       srp_password_file = hvec[1];
       
       FILE *fp = fopen(srp_password_file.c_str(), "r");
       
       if (!fp)
           throw ConfigurationError("Failed to open SRP password file", nline);
       
       char buff[ 1024 ];
       int  nread = 0;
       
       nread = fread(buff, 1, sizeof(buff), fp);
       
       srp_password = std::string( buff, nread );
       
       fclose(fp);
   }
   

   ClientConfig::ClientConfig( const std::string & cfg_file )
   {
       ifstream ifile2(cfg_file.c_str());
       
       string line;
       SV     svec;
       SV     raw;
       
       int  nline = 0;
       
       while ( !ifile2.eof() )
       {    
           nline    += 1;
           svec.clear();
           raw.clear();
           
           getline(ifile2, line);
           
           split( raw, line, is_any_of(" \t") );
           
           BOOST_FOREACH( std::string s, raw )
           {
               if ( s != "" && s[0] != '#' )
                   svec.push_back( s );
           }
           
           if (svec.size() == 0 )
               continue;
           
           if (svec[0] == "server")
           {
               ServerCFG cfg;
               cfg.frontend_cfg = this;
               
               parse_server( svec, nline, cfg );
               
               servers.insert( cfg );
           }
           else if ( svec[0] == "srp" )
           {
               parse_srp( svec, nline, srp_username, srp_password_file, srp_password );
           }
       }
       
       cout << "-------------------------" << endl;
       
       std::cout << "----------------------" << std::endl;
       std::cout << "- Fontend Configuration" << std::endl;
       std::cout << " SRP Username     : " << srp_username << std::endl;
       std::cout << " SRP Password file: " << srp_password_file << std::endl;
       std::cout << " SRP Password     : " << srp_password << std::endl;
       std::cout << "----------------------" << std::endl;
       std::cout << "- Server Configuration" << std::endl;
       
       BOOST_FOREACH( ServerCFG s, servers )
       {
           std::cout << "Host: " << s.hostname << "  Port: " << s.port << " SSL: " << s.use_ssl << " SRP: " << s.use_srp << std::endl;
       }
       
   }
   
   
}// end namespace dhd::client
}// end namespace dhd



